use std::{net::{TcpListener,TcpStream},
        io::{prelude::*,BufReader,BufWriter},
        fs};
fn main() {
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
    for stream in listener.incoming() {
        //incoming 会返回一个迭代器，它每一次迭代都会返回一个新的连接 stream(客户端发起，web服务器监听接收)
        let stream = stream.unwrap();
        //我们并不是在迭代一个一个连接，而是在迭代处理一个一个请求建立连接的尝试
        println!("Connection established");
        handle_connection_advanced(stream);
    }
}
fn handle_connection_advanced(mut stream:TcpStream) {
    let mut buf_reader = BufReader::new(&mut stream);
    let request_line = buf_reader.lines().next().unwrap().unwrap();
    let (status_line, filename) = if request_line == "GET / HTTP/1.1" {
        ("HTTP/1.1 200 OK","hello.html")
    }else {
        ("HTTP/1.1 404 NOT FOUND","404.html")
    };
    let contents = fs::read_to_string(filename).unwrap();
    let length = contents.len();
    let response = format!("{}Content-Length: {}\r\n\r\n{}", status_line, length, contents);
    stream.write_all(response.as_bytes()).unwrap();

}
fn handle_connection(mut stream:TcpStream) {
    let buf_reader = BufReader::new(&mut stream);
    let http_request : Vec<_> = buf_reader
                                .lines()//使用 lines 方法来获取一个迭代器，可以对传输的内容流进行按行迭代读取
                                .map(|result| result.unwrap())
                                .take_while(|line| !line.is_empty())/*take_while() 将闭包作为参数。
                                它将在迭代器的每个元素上调用此闭包，
                                并在返回 true 时产生元素。返回 false 后，take_while() 的工作就结束了，其余元素将被忽略*/
                                .collect();
    println!("Request: {:#?}",http_request);//{:#?} 与 {:?} 几乎一样，唯一的区别在于它能更优美地输出内容
/*        let response = "HTTP/1.1 200 OK\r\n\r\n";
    println!("{:?}",response.as_bytes());//输出为[72, 84, 84, 80, 47, 49, 46, 49, 32, 50, 48, 48, 32, 79, 75, 13, 10, 13, 10]
    stream.write_all(response.as_bytes()).unwrap();//由于 write_all 方法接受 &[u8] 类型作为参数，这里需要用 as_bytes 将字符串转换为字节数组
*/
    let status_line = "HTTP/1.1 200 OK\r\n\r\n";
    let contents = fs::read_to_string("hello.html").unwrap();//在项目的根目录下创建的hello.html
    let length = contents.len();
    let response = format!("{}\r\nContent-Length: {}\r\n\r\n{}", status_line, length, contents);
    stream.write_all(response.as_bytes()).unwrap();
}
